package test.yzx.pproject.util;

import android.animation.Animator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;

import test.yzx.pproject.R;
import test.yzx.pproject.ViewAnimatorUtil;

public class CPUAnimView extends View {
    public CPUAnimView(Context context) {
        super(context);
    }
    public CPUAnimView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public CPUAnimView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    public void start(){
        if(hasStart) return ;
        hasStart = true;
        post(new Runnable() {
            public void run() {
                animDown();
            }
        });
    }
    public void stop(){
        cancelAnim();
        if(bmp!=null){
            bmp.recycle();
            bmp = null;
        }
        hasStart = false;
    }

    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

    private void cancelAnim(){
        if(upAnim!=null){
            upAnim.cancel();
            upAnim=null;
        }
        if(downAnim != null){
            downAnim.cancel();
            downAnim=null;
        }
    }
    private void animDown(){
        if(!hasStart) return ;
        cancelAnim();
        downAnim = ViewAnimatorUtil.make(duration, 0, new AccelerateDecelerateInterpolator(), new ViewAnimatorUtil.SimpleValueCallback(){
            public void onUpdate(Animator animation, float value) {
                nowClipHeight = (int)value;
                invalidate();
            }
            public void onComplete(Animator animation) {
                animUp();
            }
        }, drawPadding, getHeight()-drawPadding);
        downAnim.start();
    }
    private void animUp(){
        if(!hasStart) return ;
        cancelAnim();
        upAnim = ViewAnimatorUtil.make(duration, 0, new AccelerateDecelerateInterpolator(), new ViewAnimatorUtil.SimpleValueCallback(){
            public void onUpdate(Animator animation, float value) {
                nowClipHeight = (int)value;
                invalidate();
            }
            public void onComplete(Animator animation) {
                animDown();
            }
        }, getHeight()-drawPadding, drawPadding);
        upAnim.start();
    }


    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    {paint.setStrokeCap(Paint.Cap.ROUND);}
    private int strokeWidth = 4;
    {paint.setStrokeWidth(strokeWidth);}
    private Animator upAnim, downAnim;
    private final int duration = 6000;
    private boolean hasStart = false;
    private int nowClipHeight = 0;
    private Bitmap bmp;
    private int halfViewWidth, halfViewHeight, halfBmpHeight, halfBmpWidth, radius;
    private int fillCircleRadius = 10;
    private int drawPadding = fillCircleRadius / 2;
    private int layerColor = Color.argb(30, 255, 255, 255);
    private int bgCircleColor = Color.argb(70, 255, 255, 255);


    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        halfViewWidth = getMeasuredWidth()>>1;
        halfViewHeight = getMeasuredHeight()>>1;
        radius = halfViewWidth - drawPadding*2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if(bmp == null){
            Bitmap temp = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
            bmp = Bitmap.createScaledBitmap(temp, getWidth()/3*2, getHeight()/3*2, true);
            temp.recycle();
            halfBmpHeight = bmp.getHeight()>>1;
            halfBmpWidth = bmp.getWidth()>>1;
        }

        /* draw background circle */
        canvas.save();
        paint.setStyle(Paint.Style.STROKE);
        canvas.translate(halfViewWidth, halfViewHeight);
        paint.setColor(bgCircleColor);
        canvas.drawCircle(0, 0, radius, paint);
        canvas.restore();

        /* draw dynamic circle */
        canvas.save();
        paint.setColor(Color.WHITE);
        canvas.clipRect(0, 0, getWidth(), nowClipHeight);
        canvas.translate(halfViewWidth, halfViewHeight);
        canvas.drawCircle(0, 0, radius, paint);
        canvas.restore();

        /* draw bmp */
        canvas.save();
        canvas.clipRect(0, 0, getWidth(), nowClipHeight);
        canvas.drawBitmap(bmp, halfViewWidth-halfBmpWidth, halfViewHeight - halfBmpHeight, null);
        canvas.restore();

        /* draw layer */
        canvas.save();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(layerColor);
        canvas.clipRect(0, 0, getWidth(), nowClipHeight);
        canvas.translate(halfViewWidth, halfViewHeight);
        canvas.drawCircle(0, 0, radius, paint);
        canvas.restore();

        /* draw landscape line and fill circle */
        canvas.save();
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);
        int y = nowClipHeight;
        int halfLandscapeLineLen = getTwoPointLengthOnCircle(radius, Math.abs(radius-nowClipHeight));
        int xStart = radius + fillCircleRadius - halfLandscapeLineLen;
        int xEnd = xStart +halfLandscapeLineLen*2;
        canvas.drawLine(xStart, y, xEnd, y, paint);
        canvas.restore();
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, widthMeasureSpec);
    }

    private int getTwoPointLengthOnCircle(int radius, int height){
        return (int) Math.sqrt(radius*radius - height*height);
    }

}
